package org.lgiavedoni.android.franq.service.phone.calendar.dao.imp;

import java.util.ArrayList;
import java.util.List;

import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.NonRepeatableRequestException;
import org.lgiavedoni.android.franq.core.calendar.Calendar;
import org.lgiavedoni.android.franq.core.calendar.CalendarEvent;
import org.lgiavedoni.android.franq.service.log.Logger;
import org.lgiavedoni.android.franq.service.phone.calendar.dao.CalendarDAO;
import org.lgiavedoni.android.franq.service.phone.calendar.dao.imp.webModel.CalendarEntry;
import org.lgiavedoni.android.franq.service.phone.calendar.dao.imp.webModel.CalendarFeed;
import org.lgiavedoni.android.franq.service.phone.calendar.dao.imp.webModel.CalendarUrl;
import org.lgiavedoni.android.franq.service.phone.calendar.dao.imp.webModel.EventEntry;
import org.lgiavedoni.android.franq.service.phone.calendar.dao.imp.webModel.EventFeed;
import org.lgiavedoni.android.franq.service.phone.calendar.dao.imp.webModel.When;
import org.lgiavedoni.android.franq.util.phone.AccountUtil;

import com.google.api.client.http.HttpTransport;
import com.google.api.client.util.DateTime;

public class CalendarWebDAO implements CalendarDAO {

	@Override
	public List<Calendar> getAllCalendars() {
		List<Calendar> calendars = new ArrayList<Calendar>();
		HttpTransport httpTransport = AccountUtil.getHttpTransport();
		if (httpTransport == null)
			return calendars;
		try {
			CalendarUrl url = CalendarUrl.forAllCalendarsFeed();
			CalendarFeed feed = CalendarFeed.executeGet(httpTransport, url);
			calendars.addAll(feed.getEntries());
		} catch (Exception ex) {
			Logger.inst.error(ex);
		}
		return calendars;
	}

	@Override
	public List<CalendarEvent> getAllCalendarEntryes(Calendar calendar) {
		return getAllCalendarEntryes(calendar, null);
	}

	private List<CalendarEvent> getAllCalendarEntryes(Calendar calendar, String params) {
		List<CalendarEvent> calendars = new ArrayList<CalendarEvent>();
		HttpTransport httpTransport = AccountUtil.getHttpTransport();
		if (httpTransport == null)
			return calendars;
		try {
			CalendarUrl url = CalendarUrl.forEventFeed(calendar.getId(), "private", "full");
			if (params != null) {
				url = new CalendarUrl(url.toString() + params);
			}
			EventFeed feed = EventFeed.executeGet(httpTransport, url);
			calendars.addAll(feed.getEntries());
		} catch (Exception ex) {
			Logger.inst.error(ex);
		}
		return calendars;
	}

	@Override
	public List<CalendarEvent> getFutureCalendarEntryes(Calendar calendar) {
		return getAllCalendarEntryes(calendar, "?futureevents=true");
	}

	@Override
	public Calendar createCalendar(String title) {
		HttpTransport httpTransport = AccountUtil.getHttpTransport();
		if (httpTransport == null) {
			Logger.inst.warning("AccountUtil.getHttpTransport()==null");
			return null;
		}

		try {
			CalendarUrl url = CalendarUrl.forOwnCalendarsFeed();
			CalendarEntry calendarE = new CalendarEntry();
			calendarE.title = title;
			return calendarE.executeInsert(httpTransport, url);

		} catch (Exception ex) {
			Logger.inst.error(ex);
			return null;
		}
	}

	@Override
	public void addEvent(Calendar calendar, CalendarEvent event) {
		try {
			CalendarUrl url = new CalendarUrl(((CalendarEntry) calendar).getEventFeedLink());

			EventEntry eventE = new EventEntry();
			eventE.title = event.getTitle();
			eventE.summary = event.getDescription();

			When when = new When();
			when.startTime = new DateTime(event.getStartDate());
			when.endTime = new DateTime(event.getEndDate());

			eventE.when = when;

			HttpTransport httpTransport = AccountUtil.getHttpTransport();

			try {
				/* EventEntry result = */eventE.executeInsert(httpTransport, url);
			} catch (ClientProtocolException ex) {
				if (ex.getCause() instanceof NonRepeatableRequestException) {
					// Try one more time
					eventE.executeInsert(httpTransport, url);
				} else {
					throw ex;
				}
			}
		} catch (Exception ex) {
			Logger.inst.error(ex);
		}
	}

	public void removeEvent(CalendarEvent event) {
		try {
			if (event instanceof EventEntry) {
				((EventEntry) event).executeDelete(AccountUtil.getHttpTransport());
			}
		} catch (Exception ex) {
			Logger.inst.error(ex);
		}
	}

}
